#include <iostream>
#include <memory>

class Observer {
 public:
  virtual ~Observer() {}
  virtual void update() = 0;
};

#include <algorithm>
#include <vector>

class Observable {
  std::vector<std::weak_ptr<Observer>> observers_;

 public:
  void addObserver(std::weak_ptr<Observer> observer) {
    observers_.push_back(observer);
  }
  void removeObserver(std::weak_ptr<Observer> observer) {
    auto sp = observer.lock();
    auto it = std::find_if(
        observers_.begin(), observers_.end(),
        [&](const std::weak_ptr<Observer>& wp) { return sp == wp.lock(); });
    if (it != observers_.end()) {
      observers_.erase(it);
    }
  }

  void notifyObservers() {
    for (auto it = observers_.begin(); it != observers_.end();) {
      auto observer = it->lock();
      if (observer) {
        observer->update();
        it++;
      } else {
        observers_.erase(it);
      }
    }
  }
};

class ConcreteObserver : public Observer,
                         public std::enable_shared_from_this<ConcreteObserver> {
  std::shared_ptr<Observable> observable_;

 public:
  ConcreteObserver(std::shared_ptr<Observable> observable)
      : observable_(observable) {
    // 没有构建完成，terminate called after throwing an instance of
    // 'std::bad_weak_ptr'
    // observable_->addObserver(shared_from_this());
  }

  void addObserver() { observable_->addObserver(shared_from_this()); }

  ~ConcreteObserver() {}

  void update() { std::cout << "sdddddds\n"; }
};

int main(int argc, char const* argv[]) {
  auto observable = std::make_shared<Observable>();
  auto observer1 = std::make_shared<ConcreteObserver>(observable);
  // observer1->addObserver();
  auto observer2 = std::make_shared<ConcreteObserver>(observable);
  // observer1->addObserver();
  observable->notifyObservers();
  return 0;
}
